
__author__ = 'DSperansky'

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import random

import unittest

list_movies = [['My movie ' + str(random.choice(range(1,100))), '2012', 'This movie will be created and should be found']
                ,['Terminator X', '2025', 'This movie should not be found']]

class TestSearch(unittest.TestCase):

    driver = None

    @staticmethod
    def setUpClass():
        TestSearch.driver = webdriver.Firefox()
        #TestCreateDelete.driver.maximize_window()

    def setUp(self):
        self.wait = WebDriverWait(TestSearch.driver, 15)
        self.driver.implicitly_wait(15)
        self.base_url = "http://localhost/"
        self.verificationErrors = []
        self.accept_next_alert = True
        self.do_login()
        self.create_movie()
        self.load_main_page()
        self.clear_search_input()

    def test_1_search_positive(self):
        """
            Test of searching for existing movie - movie should be found
        """
        search_input_css_locator = "div.searchbox>input#q"
        search_input = self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, search_input_css_locator)))
        search_input.send_keys(list_movies[0][0])
        old_element_css_locator = "div#results>*:first-child"
        old_element =  self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, old_element_css_locator)))
        search_input.send_keys(Keys.RETURN)
        self.wait.until(EC.staleness_of(old_element))
        self.assertTrue(self.verify_search_result(list_movies[0][0]))

    def test_2_search_negative(self):
        """
            Test of searching for non-existing movie - movie should not be found
        """
        search_input_css_locator = "div.searchbox>input#q"
        search_input = self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, search_input_css_locator)))
        search_input.send_keys(list_movies[1][0])
        old_element_css_locator = "div#results>*:first-child"
        old_element =  self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, old_element_css_locator)))
        search_input.send_keys(Keys.RETURN)
        self.wait.until(EC.staleness_of(old_element))
        self.assertTrue(self.verify_search_result(list_movies[1][0], positive=False))

    def create_movie(self):
        """ Creates new movie foe search tests """
        add_movie_css_locator = "nav li:first-of-type>div.button img"
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, add_movie_css_locator))).click()
        #On edit movie page
        self.fill_movie_form(list_movies[0])

    def delete_movie(self):
        """
            Deletes movie created for search tests
        """
        id = self.get_movie_id_by_title(list_movies[0][0])
        if id:
            movie_with_id_css_locator = "div#results>a>div[id='movie_" + str(id) +"']"
            self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, movie_with_id_css_locator))).click()
            delete_button_css_locator = "nav li:last-of-type>div.button img"
            self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, delete_button_css_locator))).click()
            self.wait.until(EC.alert_is_present()).accept()
        else:
            print 'No movies found - nothing to delete!'

    def get_movie_ids(self):
        """
            Method returns list of movie id's
        """
        all_movies_css_locator = "div#results>a>div"
        wait = WebDriverWait(TestSearch.driver, 5)
        try:
            lst_movies = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, all_movies_css_locator)))
            lst_ids = [str(movie.get_attribute("id")).split('_')[1] for movie in lst_movies]
        except TimeoutException, e:
            lst_ids = []
        return lst_ids

    def verify_search_result(self, title, positive=True):
        """
            Method verifies result of search according to given parameters
        """
        lst_ids = self.get_movie_ids()
        if positive and len(lst_ids) == 0:
            return False
        if not positive and len(lst_ids) == 0:
            return True
        if positive and len(lst_ids) > 0:
            return self.get_movie_id_by_title(title)
        return False

    def get_movie_id_by_title(self, title):
        """
            Method returns id for a movie by it's title
        """
        wait = WebDriverWait(TestSearch.driver, 5)
        lst_ids = self.get_movie_ids()
        for id in lst_ids:
            movie_with_id_css_locator = "div#results>a>div[id='movie_" + str(id) +"']"
            movie_elem = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, movie_with_id_css_locator)))
            movie_title = movie_elem.find_element_by_class_name('title').text
            if title == movie_title:
                return id
        return 0

    def is_movie_info_page(self):
        """ Method verifies that Movie info page is displayed """
        current_url = str(self.driver.current_url)
        if current_url.count('=') == 2:
            url_split = current_url.split('=')
            if url_split[2].isdigit():
                return True
            return False
        return False

    def fill_movie_form(self, movie):
        """ Method fills movie information on edit movie page """
        #On edit movie page
        title_input_css_locator = "input[name='name']"
        year_input_css_locator = "input[name='year']"
        notes_tarea_css_locator = "textarea[name='notes']"
        save_button_css_locator = "input#submit"
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  title_input_css_locator))).send_keys(movie[0])
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  year_input_css_locator))).send_keys(movie[1])
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  notes_tarea_css_locator))).send_keys(movie[2])
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  save_button_css_locator))).click()

    def load_main_page(self):
        """ Method loads main page """
        home_link_css_locator = "header nav li:first-of-type>a"
        results_element_css_locator = "div#results>*:first-child"
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  home_link_css_locator))).click()
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, results_element_css_locator)))

    def clear_search_input(self):
        """
            Method clears search input
        """
        search_input_css_locator = "div.searchbox>input#q"
        search_input = self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, search_input_css_locator)))
        search_input.clear()
        old_element_css_locator = "div#results>*:first-child"
        old_element =  self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, old_element_css_locator)))
        search_input.send_keys(Keys.RETURN)
        self.wait.until(EC.staleness_of(old_element))

    def do_login(self):
        """ Method loads initial page and performs login """
        #driver = self.driver
        self.driver.get(self.base_url + "/php4dvd/")
        self.wait.until(EC.visibility_of_element_located((By.ID,"username"))).clear()
        self.wait.until(EC.visibility_of_element_located((By.ID,"username"))).send_keys("admin")
        self.wait.until(EC.visibility_of_element_located((By.NAME,"password"))).clear()
        self.wait.until(EC.visibility_of_element_located((By.NAME,"password"))).send_keys("admin")
        self.wait.until(EC.visibility_of_element_located((By.NAME,"submit"))).click()

    def do_logout(self):
        """ Method performs logout procedure """
        logout_link_css_locator = "header nav li:last-of-type>a"
        self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,  logout_link_css_locator))).click()
        self.wait.until(EC.alert_is_present()).accept()



    def tearDown(self):
        self.load_main_page()
        self.clear_search_input()
        self.delete_movie()
        self.do_logout()
        self.assertEqual([], self.verificationErrors)

    @staticmethod
    def tearDownClass():
        TestSearch.driver.quit()

if __name__ == "__main__":
    unittest.main()

